﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Windows.UI
{

    static class ColorTranslator
    {
    /// <summary>
    /// Go from HTML Hex # to Ole Color Code
    /// </summary>
    /// <param name="htmlcolor"></param>
    /// <returns>returns an int that represents a Ole Color Code</returns>
        public static int FromHtmltoOle(string htmlcolor)
        {
            return ToOle(FromHtml(htmlcolor));
        }
        /// <summary>
        /// Go from HTML Hex # to Win32 Color code
        /// </summary>
        /// <param name="htmlcolor"></param>
        /// <returns>returns an int that represents a Win32 Color Code</returns>
        public static int FromHtmltoWin32(string htmlcolor)
        {
            return ToWin32(FromHtml(htmlcolor));
        }
        /// <summary>
        /// This returns the .Net Color from a Hex#
        /// </summary>
        /// <param name="htmlColor"></param>
        /// <returns>Returns a Net Color</returns>
        public static Color FromHtml(string htmlColor)
        {
            byte rvalue = (byte)HexToInt(htmlColor.Substring(1, 2));
            byte gvalue = (byte)HexToInt(htmlColor.Substring(3, 2));
            byte bvalue = (byte)HexToInt(htmlColor.Substring(5, 2));
            return Color.FromArgb(255, rvalue, gvalue, bvalue);
        }
        /// <summary>
        /// Translates an Net Color to a hexadecimal color code
        /// </summary>
        /// <param name="c">c = a net color</param>
        /// <returns>returns the hex color</returns>
        public static string ToHtml(Color c)
        {
            return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
        }
        /// <summary>
        /// Translate an Ole to an Hex #
        /// </summary>
        /// <param name="oleColor"></param>
        /// <returns>A string that represents a Hex color #</returns>
        public static string FromOletoHtml(this int oleColor)
        {
            return ToHtml(FromOle(oleColor));
        }
        /// <summary>
        /// This takes an Ole color code and turns it into a Win32
        /// </summary>
        /// <param name="oleColor"></param>
        /// <returns>returns an int that represents an OLE color code</returns>
        public static int FromOletoWin32(this int oleColor)
        {
            return ToWin32(FromOle(oleColor));
        }
        /// <summary>
        /// This receives a win32 color code in the form of an int and returns the hex # code
        /// </summary>
        /// <param name="win32color"></param>
        /// <returns>returns a string that represents a Hex# color code</returns>
        public static string FromWin32tohtml(this int win32color)
        {
            return ToHtml(FromWin32(win32color));
        }
        /// <summary>
        /// This takes a win32 color and returns an ole color code
        /// </summary>
        /// <param name="win32color"></param>
        /// <returns>An int that represents an ole color code</returns>
        public static int FromWin32toOle(this int win32color)
        {
            return ToOle(FromWin32(win32color));
        }
        /// <summary> 
        /// Translates an Ole color value to .Net Color
        /// </summary>
        /// <param name="oleColor"></param>
        /// <returns>returns a Net Color representing the oleColor</returns>
        public static Color FromOle(this int oleColor)
        {
            byte R = (byte)((oleColor >> 0) & 0xFF);
            byte G = (byte)((oleColor >> 8) & 0xFF);
            byte B = (byte)((oleColor >> 16) & 0xFF);
            return Color.FromArgb(255, R, G, B);
        }
        /// <summary>
        /// This takes a Net Color and converts it to a Win32
        /// </summary>
        /// <param name="c"></param>
        /// <returns>Returns an int that represents a Win32 color code</returns>
        public static int ToWin32(Color c)
        {
            return c.R | c.G << 8 | c.B << 16;
        }
        /// <summary>
        /// This takes a Win32 color code and returns a Net Color
        /// </summary>
        /// <param name="win32Color"></param>
        /// <returns>A new color that represents the win32 color code</returns>
        public static Color FromWin32(int win32Color)
        {
            return FromOle(win32Color);
        }
        /// <summary> 
        /// Translates the specified .Net Color to an Ole color. 
        /// </summary>  
        public static int ToOle(Color oldColor)
        {
            return oldColor.R << 0 | oldColor.G << 8 | oldColor.B << 16;
        }
        /// <summary>
        /// This converts a Hex # to a regular int
        /// </summary>
        /// <param name="hexstr"></param>
        /// <returns>an int that represents the hex #</returns>
        private static int HexToInt(string hexstr)
        {
            return Convert.ToInt32(hexstr, 16);

        }
        /// <summary>
        /// This converts a Net Color to an HSL code that represents the color
        /// </summary>
        /// <param name="oldColor"></param>
        /// <returns>An HSLColor that represents the net color</returns>
        public static HslColor ToHsl(Color oldColor)
        {
            byte r = oldColor.R;
            byte g = oldColor.G;
            byte b = oldColor.B;
            return RgbToHsl((int)r, (int)g, (int)b);
        }
        private static HslColor RgbToHsl(int Red, int Green, int Blue)
        {
            double huevalue;
            double satvalue;
            double rval2 = ((double)Red) / 255.0;
            double gval2 = ((double)Green) / 255.0;
            double bval2 = ((double)Blue) / 255.0;
            double num = Math.Min(Math.Min(rval2, gval2), bval2);
            double m = Math.Max(Math.Max(rval2, gval2), bval2);
            double lightvalue = m;
            double vm = m - num;
            if ((m == 0.0) || (vm == 0.0))
            {
                satvalue = 0.0;
                huevalue = 0.0;
            }
            else
            {
                satvalue = vm / m;
                if (rval2 == m)
                {
                    huevalue = (gval2 - bval2) / vm;
                }
                else if (gval2 == m)
                {
                    huevalue = 2.0 + ((bval2 - rval2) / vm);
                }
                else
                {
                    huevalue = 4.0 + ((rval2 - gval2) / vm);
                }
            }
            huevalue *= 60.0;
            if (huevalue < 0.0)
            {
                huevalue += 360.0;
            }
            return new HslColor((int)huevalue, (int)(satvalue * 100.0), (int)(lightvalue * 100.0));
        }
        /// <summary>
        /// This converts an HSL color code to a Hex#
        /// </summary>
        /// <param name="oldcolor"></param>
        /// <returns>An hex # that represents an hsl</returns>
        public static string HslToHtml(HslColor oldcolor)
        {
            return ToHtml(FromHsl(oldcolor));
        }
        /// <summary>
        /// This translate a HSL code to a net code
        /// </summary>
        /// <param name="oldcolor"></param>
        /// <returns>A net color code that represrnts the hsl color</returns>
        public static Color FromHsl(HslColor oldcolor)
        {
            double rvalue = 0.0;
            double gvalue = 0.0;
            double bvalue = 0.0;
            double num = ((double)oldcolor.Hue) % 360.0;
            double num2 = ((double)oldcolor.Saturation) / 100.0;
            double v = ((double)oldcolor.Lightness) / 100.0;
            if (num2 == 0.0)
            {
                rvalue = v;
                gvalue = v;
                bvalue = v;
            }
            else
            {
                double d = num / 60.0;
                int sextant = (int)Math.Floor(d);
                double fract = d - sextant;
                double m = v * (1.0 - num2);
                double mid2 = v * (1.0 - (num2 * fract));
                double mid1 = v * (1.0 - (num2 * (1.0 - fract)));
                switch (sextant)
                {
                    case 0:
                        rvalue = v; gvalue = mid1; bvalue = m;
                        break;
                    case 1:
                        rvalue = mid2; gvalue = v; bvalue = m;
                        break;
                    case 2:
                        rvalue = m; gvalue = v; bvalue = mid1;
                        break;
                    case 3:
                        rvalue = m; gvalue = mid2; bvalue = v;
                        break;
                    case 4:
                        rvalue = mid1; gvalue = m; bvalue = v;
                        break;
                    case 5:
                        rvalue = v; gvalue = m; bvalue = mid2;
                        break;
                }
            }
            return Color.FromArgb(255, (byte)(rvalue * 255.0), (byte)(gvalue * 255.0), (byte)(bvalue * 255.0));
        }

        private static String ReverseString(String inStr)
        {
            char[] inputarray = inStr.ToCharArray();
            Array.Reverse(inputarray);
            return new string(inputarray);
        }
    }
    public class HslColor
    {
        public HslColor(int h, int s, int l)
        {
            hue = h;
            saturation = s;
            lightness = l;
        }
        private int hue;
        private int saturation;
        private int lightness;
        public int Hue
        {
            get
            {
                return hue;
            }
            set
            {
                hue = value;
            }
        }
        public int Saturation
        {
            get
            {
                return saturation;
            }
            set
            {
                saturation = value;
            }
        }
        public int Lightness
        {
            get
            {
                return lightness;
            }
            set
            {
                lightness = value;
            }
        }
        public string Value
        {
            get
            {
                return Hue + ", " + Saturation + "%, " + Lightness +"%";
            }
        }

    }
}


